<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Normal mapping</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Normal_mapping"> <link href="./mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/ext.math.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Normal_mapping rootpage-Normal_mapping skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Normal mapping</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<style data-mw-deduplicate="TemplateStyles:r1251242444">
/* start https://en.wikipedia.org/ */
.mw-parser-output .ambox{border:1px solid #a2a9b1;border-left:10px solid #36c;background-color:#fbfbfb;box-sizing:border-box}.mw-parser-output .ambox+link+.ambox,.mw-parser-output .ambox+link+style+.ambox,.mw-parser-output .ambox+link+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+style+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+link+.ambox{margin-top:-1px}html body.mediawiki .mw-parser-output .ambox.mbox-small-left{margin:4px 1em 4px 0;overflow:hidden;width:238px;border-collapse:collapse;font-size:88%;line-height:1.25em}.mw-parser-output .ambox-speedy{border-left:10px solid #b32424;background-color:#fee7e6}.mw-parser-output .ambox-delete{border-left:10px solid #b32424}.mw-parser-output .ambox-content{border-left:10px solid #f28500}.mw-parser-output .ambox-style{border-left:10px solid #fc3}.mw-parser-output .ambox-move{border-left:10px solid #9932cc}.mw-parser-output .ambox-protection{border-left:10px solid #a2a9b1}.mw-parser-output .ambox .mbox-text{border:none;padding:0.25em 0.5em;width:100%}.mw-parser-output .ambox .mbox-image{border:none;padding:2px 0 2px 0.5em;text-align:center}.mw-parser-output .ambox .mbox-imageright{border:none;padding:2px 0.5em 2px 0;text-align:center}.mw-parser-output .ambox .mbox-empty-cell{border:none;padding:0;width:1px}.mw-parser-output .ambox .mbox-image-div{width:52px}@media(min-width:720px){.mw-parser-output .ambox{margin:0 10%}}@media print{body.ns-0 .mw-parser-output .ambox{display:none!important}}
/* end https://en.wikipedia.org/ */
</style>
<p>In <a href="3D_computer_graphics" title="3D computer graphics">3D computer graphics</a>, <b>normal mapping</b>, or <b>Dot3 bump mapping</b>, is a <a href="Texture_mapping" title="Texture mapping">texture mapping</a> technique used for faking the lighting of bumps and dents – an implementation of <a href="Bump_mapping" title="Bump mapping">bump mapping</a>. It is used to add details without using more <a href="Polygonal_modeling" title="Polygonal modeling">polygons</a>.<sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup> A common use of this technique is to greatly enhance the appearance and details of a <a href="Low_poly" title="Low poly">low polygon model</a> by generating a normal map from a high polygon model or <a href="Heightmap" title="Heightmap">height map</a>.
</p><p>Normal maps are commonly stored as regular <a href="RGB" class="mw-redirect" title="RGB">RGB</a> images where the RGB components correspond to the X, Y, and Z coordinates, respectively, of the <a href="Surface_normal" class="mw-redirect" title="Surface normal">surface normal</a>.
</p>
<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="History">History</h2></div>
<p>In 1978 <a href="Jim_Blinn" title="Jim Blinn">Jim Blinn</a> described how the normals of a surface could be perturbed to make geometrically flat faces have a detailed appearance.<sup id="cite_ref-2" class="reference"><a href="#cite_note-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
The idea of taking geometric details from a high polygon model was introduced in "Fitting Smooth Surfaces to Dense Polygon Meshes" by Krishnamurthy and Levoy, Proc. <a href="SIGGRAPH" title="SIGGRAPH">SIGGRAPH</a> 1996,<sup id="cite_ref-3" class="reference"><a href="#cite_note-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup> where this approach was used for creating <a href="Displacement_mapping" title="Displacement mapping">displacement maps</a> over <a href="Nurbs" class="mw-redirect" title="Nurbs">nurbs</a>. In 1998, two papers were presented with key ideas for transferring details with normal maps from high to low polygon meshes: "Appearance Preserving Simplification", by Cohen et al. SIGGRAPH 1998,<sup id="cite_ref-4" class="reference"><a href="#cite_note-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup> and "A general method for preserving attribute values on simplified meshes" by Cignoni et al. IEEE Visualization '98.<sup id="cite_ref-5" class="reference"><a href="#cite_note-5"><span class="cite-bracket">[</span>5<span class="cite-bracket">]</span></a></sup> The former introduced the idea of storing surface normals directly in a texture, rather than displacements, though it required the low-detail model to be generated by a particular constrained simplification algorithm. The latter presented a simpler approach that decouples the high and low polygonal mesh and allows the recreation of any attributes of the high-detail model (color, <a href="Texture_mapping" title="Texture mapping">texture coordinates</a>, <a href="Displacement_mapping" title="Displacement mapping">displacements</a>, etc.) in a way that is not dependent on how the low-detail model was created. The combination of storing normals in a texture, with the more general creation process is still used by most currently available tools.
</p>
<div class="mw-heading mw-heading2"><h2 id="Spaces">Spaces</h2></div>
<p>The orientation of coordinate axes differs depending on the <a href="Vector_Space" class="mw-redirect" title="Vector Space"> space </a> in which the normal map was encoded.
A straightforward implementation encodes normals in object space so that the red, green, and blue components correspond directly with the X, Y, and Z coordinates.
In object space, the coordinate system is constant.
</p><p>However, object-space normal maps cannot be easily reused on multiple models, as the orientation of the surfaces differs.
Since color texture maps can be reused freely, and normal maps tend to correspond with a particular texture map,
it is desirable for artists that normal maps have the same property.
</p>
<p>Normal map reuse is made possible by encoding maps in <a href="Tangent_space" title="Tangent space">tangent space</a>.
The tangent space is a <a href="Vector_Space" class="mw-redirect" title="Vector Space"> vector space</a>, which is tangent to the model's surface.
The coordinate system varies smoothly (based on the derivatives of position with respect to texture coordinates) across the surface.
</p>
<p>Tangent space normal maps can be identified by their dominant purple color, corresponding to a vector facing directly out from the surface. See <a href="#Calculation"> Calculation</a>.
</p>
<div class="mw-heading mw-heading2"><h2 id="Calculating_tangent_spaces">Calculating tangent spaces</h2></div>
<p>Surface normals are used in computer graphics primarily for the purposes of lighting, through mimicking a phenomenon called <a href="Specular_reflection" title="Specular reflection">specular reflection</a>. Since the visible image of an object is the light bouncing off of its surface, the light information obtained from each point of the surface can instead be computed on its tangent space at that point.
</p>
<p>For each tangent space of a surface in 3-dimensional space, there are two vectors which are perpendicular to every vector of the tangent space. These vectors are called <a href="Normal_(geometry)" title="Normal (geometry)">normal vectors</a>, and choosing between these two vectors provides a description on how the surface is <a href="Orientability" title="Orientability">oriented</a> at that point, as the light information depends on the angle of incidence between the ray <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {r} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">r</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {r} }</annotation>
</semantics>
</math></span><img src="./eca0f46511c4c986c48b254073732c0bd98ae0c1.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.102ex; height:1.676ex;" alt="{\displaystyle \mathbf {r} }" loading="lazy"></span> and the normal vector <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {n} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {n} }</annotation>
</semantics>
</math></span><img src="./4a720c341f39f52fd96028dab83edd34d400be46.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.485ex; height:1.676ex;" alt="{\displaystyle \mathbf {n} }" loading="lazy"></span>, and the light will only be visible if <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {r} \cdot \mathbf {n} >0}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">r</mi>
</mrow>
<mo>⋅<!-- ⋅ --></mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
<mo>></mo>
<mn>0</mn>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {r} \cdot \mathbf {n} >0}</annotation>
</semantics>
</math></span><img src="./640b6a2fc05ade59e145b6b07ca0f489d7ea55d9.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:8.527ex; height:2.176ex;" alt="{\displaystyle \mathbf {r} \cdot \mathbf {n} >0}" loading="lazy"></span>. In such a case, the reflection <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {s} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">s</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {s} }</annotation>
</semantics>
</math></span><img src="./644ae690160e658898a141e568a7fb0ee6040004.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.056ex; height:1.676ex;" alt="{\displaystyle \mathbf {s} }" loading="lazy"></span> of the ray with direction <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {r} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">r</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {r} }</annotation>
</semantics>
</math></span><img src="./eca0f46511c4c986c48b254073732c0bd98ae0c1.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.102ex; height:1.676ex;" alt="{\displaystyle \mathbf {r} }" loading="lazy"></span> along the normal vector <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {n} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {n} }</annotation>
</semantics>
</math></span><img src="./4a720c341f39f52fd96028dab83edd34d400be46.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.485ex; height:1.676ex;" alt="{\displaystyle \mathbf {n} }" loading="lazy"></span> is given by
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {s} =\mathbf {r} -2(\mathbf {r} \cdot \mathbf {n} )\mathbf {n} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">s</mi>
</mrow>
<mo>=</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">r</mi>
</mrow>
<mo>−<!-- − --></mo>
<mn>2</mn>
<mo stretchy="false">(</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">r</mi>
</mrow>
<mo>⋅<!-- ⋅ --></mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {s} =\mathbf {r} -2(\mathbf {r} \cdot \mathbf {n} )\mathbf {n} }</annotation>
</semantics>
</math></span><img src="./51d334c55154f888ef7992a17b8d5e25a34214b3.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:16.82ex; height:2.843ex;" alt="{\displaystyle \mathbf {s} =\mathbf {r} -2(\mathbf {r} \cdot \mathbf {n} )\mathbf {n} }" loading="lazy"></span></dd></dl>
<p>where the <a href="Vector_projection" title="Vector projection">projection</a> of the ray onto the normal is <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle (\mathbf {r} \cdot \mathbf {n} )\mathbf {n} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mo stretchy="false">(</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">r</mi>
</mrow>
<mo>⋅<!-- ⋅ --></mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle (\mathbf {r} \cdot \mathbf {n} )\mathbf {n} }</annotation>
</semantics>
</math></span><img src="./4672767d9b60878668eb355681ec1bcb2fa7ff07.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:7.561ex; height:2.843ex;" alt="{\displaystyle (\mathbf {r} \cdot \mathbf {n} )\mathbf {n} }" loading="lazy"></span>.
</p><p>Intuitively, this just means that you can only see the outward face of an object if you're looking from the outside, and only see the inward face if you're looking from the inside. Note that the light information is local, and so the surface does not necessarily need to be orientable as a whole. This is why even though spaces such as the <a href="M%C3%B6bius_strip" title="Möbius strip">Möbius strip</a> and the <a href="Klein_bottle" title="Klein bottle">Klein bottle</a> are non-orientable, it is still possible to visualize them.
</p>
<p>Normals can be specified with a variety of coordinate systems. In computer graphics, it is useful to compute normals relative to the tangent plane of the surface.
This is useful because surfaces in applications undergo a variety of transforms, such as in the process of being rendered, or in skeletal animations, and so it is important for the normal vector information to be preserved under these transformations.
Examples of such transforms include
transformation, rotation, shearing and scaling, perspective projection,<sup id="cite_ref-6" class="reference"><a href="#cite_note-6"><span class="cite-bracket">[</span>6<span class="cite-bracket">]</span></a></sup> or the skeletal animations on a finely detailed character.
</p><p>For the purposes of computer graphics, the most common representation of a surface is a <a href="Triangulation_(topology)" title="Triangulation (topology)">triangulation</a>, and as a result, the tangent plane at a point can be obtained through interpolating between the planes that contain the triangles that each intersect that point.
Similarly, for <a href="Parametric_surface" title="Parametric surface">parametric surfaces</a> with tangent spaces, the parametrizations will yield partial derivatives, and these derivatives can be <a href="Tangent_space#Tangent_vectors_as_directional_derivatives" title="Tangent space">used as a basis of the tangent spaces at every point</a>.
</p><p>In order to find the perturbation in the normal the tangent space must be correctly calculated.<sup id="cite_ref-7" class="reference"><a href="#cite_note-7"><span class="cite-bracket">[</span>7<span class="cite-bracket">]</span></a></sup> Most often the normal is perturbed in a fragment shader after applying the model and view matrices. Typically the geometry provides a normal and tangent. The tangent is part of the tangent plane and can be transformed simply with the <a href="Affine_transformation" title="Affine transformation">linear</a> part of the matrix (the upper 3x3). However, the normal needs to be transformed by the <a href="Surface_normal" class="mw-redirect" title="Surface normal">inverse transpose</a>. Most applications will want bitangent to match the transformed geometry (and associated UVs). So instead of enforcing the bitangent to be perpendicular to the tangent, it is generally preferable to transform the bitangent just like the tangent. Let <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {t} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">t</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {t} }</annotation>
</semantics>
</math></span><img src="./16ff63cc74a931900e79b3caacbae3fa8cc66845.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.039ex; height:2.009ex;" alt="{\displaystyle \mathbf {t} }" loading="lazy"></span> be tangent, <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {b} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">b</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {b} }</annotation>
</semantics>
</math></span><img src="./13ebf4628a1adf07133a6009e4a78bdd990c6eb9.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.485ex; height:2.176ex;" alt="{\displaystyle \mathbf {b} }" loading="lazy"></span> be bitangent, <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {n} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {n} }</annotation>
</semantics>
</math></span><img src="./4a720c341f39f52fd96028dab83edd34d400be46.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:1.485ex; height:1.676ex;" alt="{\displaystyle \mathbf {n} }" loading="lazy"></span> be normal, <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {M} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">M</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {M} }</annotation>
</semantics>
</math></span><img src="./e499ae5946af9c09777ada933051b3669d3372c2.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:2.537ex; height:2.176ex;" alt="{\displaystyle \mathbf {M} }" loading="lazy"></span> be the linear part of the 3x3 model matrix, and <span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {V} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">V</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {V} }</annotation>
</semantics>
</math></span><img src="./c0048514530d0c0fb8a7beb795110815a818784d.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:2.019ex; height:2.176ex;" alt="{\displaystyle \mathbf {V} }" loading="lazy"></span> be the linear part of the 3x3 view matrix.
</p>
<dl><dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {t} '=\mathbf {V} \mathbf {M} \mathbf {t} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">t</mi>
</mrow>
<mo>′</mo>
</msup>
<mo>=</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">V</mi>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">M</mi>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">t</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {t} '=\mathbf {V} \mathbf {M} \mathbf {t} }</annotation>
</semantics>
</math></span><img src="./6fdfc552cea6c5c4d5aa79dcda353fd72ce6464b.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:10.419ex; height:2.509ex;" alt="{\displaystyle \mathbf {t} '=\mathbf {V} \mathbf {M} \mathbf {t} }" loading="lazy"></span></dd>
<dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {b} '=\mathbf {V} \mathbf {M} \mathbf {b} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">b</mi>
</mrow>
<mo>′</mo>
</msup>
<mo>=</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">V</mi>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">M</mi>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">b</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {b} '=\mathbf {V} \mathbf {M} \mathbf {b} }</annotation>
</semantics>
</math></span><img src="./1f5533a31b6bac86e675f17e21cde5dd8bd9cdb0.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.338ex; width:11.311ex; height:2.509ex;" alt="{\displaystyle \mathbf {b} '=\mathbf {V} \mathbf {M} \mathbf {b} }" loading="lazy"></span></dd>
<dd><span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle \mathbf {n} '=((\mathbf {V} \mathbf {M} )^{-1})^{T}\mathbf {n} =(\mathbf {M} ^{-1}\mathbf {V} ^{-1})^{T}\mathbf {n} =(\mathbf {V} ^{-1})^{T}(\mathbf {M} ^{-1})^{T}\mathbf {n} }">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
<mo>′</mo>
</msup>
<mo>=</mo>
<mo stretchy="false">(</mo>
<mo stretchy="false">(</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">V</mi>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">M</mi>
</mrow>
<msup>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mo>−<!-- − --></mo>
<mn>1</mn>
</mrow>
</msup>
<msup>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi>T</mi>
</mrow>
</msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
<mo>=</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">M</mi>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>−<!-- − --></mo>
<mn>1</mn>
</mrow>
</msup>
<msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">V</mi>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>−<!-- − --></mo>
<mn>1</mn>
</mrow>
</msup>
<msup>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi>T</mi>
</mrow>
</msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
<mo>=</mo>
<mo stretchy="false">(</mo>
<msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">V</mi>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>−<!-- − --></mo>
<mn>1</mn>
</mrow>
</msup>
<msup>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi>T</mi>
</mrow>
</msup>
<mo stretchy="false">(</mo>
<msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">M</mi>
</mrow>
<mrow class="MJX-TeXAtom-ORD">
<mo>−<!-- − --></mo>
<mn>1</mn>
</mrow>
</msup>
<msup>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mi>T</mi>
</mrow>
</msup>
<mrow class="MJX-TeXAtom-ORD">
<mi mathvariant="bold">n</mi>
</mrow>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle \mathbf {n} '=((\mathbf {V} \mathbf {M} )^{-1})^{T}\mathbf {n} =(\mathbf {M} ^{-1}\mathbf {V} ^{-1})^{T}\mathbf {n} =(\mathbf {V} ^{-1})^{T}(\mathbf {M} ^{-1})^{T}\mathbf {n} }</annotation>
</semantics>
</math></span><img src="./0b7bbecb1bbe79b2ad385f28e97202c61fc70175.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:55.86ex; height:3.176ex;" alt="{\displaystyle \mathbf {n} '=((\mathbf {V} \mathbf {M} )^{-1})^{T}\mathbf {n} =(\mathbf {M} ^{-1}\mathbf {V} ^{-1})^{T}\mathbf {n} =(\mathbf {V} ^{-1})^{T}(\mathbf {M} ^{-1})^{T}\mathbf {n} }" loading="lazy"></span></dd></dl>
<div class="mw-heading mw-heading2"><h2 id="Calculation">Calculation</h2></div>
<p>To calculate the <a href="Lambertian_reflectance" title="Lambertian reflectance">Lambertian</a> (diffuse) lighting of a surface, the unit <a href="Vector_(geometric)" class="mw-redirect" title="Vector (geometric)">vector</a> from the shading point to the light source is <a href="Dot_product" title="Dot product">dotted</a> with the unit vector normal to that surface, and the result is the intensity of the light on that surface. Imagine a polygonal model of a sphere - you can only approximate the shape of the surface. By using a 3-channel bitmap textured across the model, more detailed normal vector information can be encoded. Each channel in the bitmap corresponds to a spatial dimension (X, Y and Z). These spatial dimensions are relative to a constant coordinate system for object-space normal maps, or to a smoothly varying coordinate system (based on the derivatives of position with respect to texture coordinates) in the case of tangent-space normal maps. This adds much more detail to the surface of a model, especially in conjunction with advanced lighting techniques.
</p><p>Unit Normal vectors corresponding to the u,v texture coordinate are mapped onto normal maps. Only vectors pointing towards the viewer (z: 0 to -1 for <a href="Orientation_(vector_space)" title="Orientation (vector space)">Left Handed Orientation</a>) are present, since the vectors on geometries pointing away from the viewer are never shown. The mapping is as follows:
</p>
<pre> X: -1 to +1 : Red: 0 to 255
Y: -1 to +1 : Green: 0 to 255
Z: 0 to -1 : Blue: 128 to 255
</pre>
<pre> light green light yellow
dark cyan light blue light red
dark blue dark magenta
</pre>
<ul><li>A normal pointing directly towards the viewer (0,0,-1) is mapped to (128,128,255). Hence the parts of object directly facing the viewer are light blue. The most common color in a normal map.</li>
<li>A normal pointing to top right corner of the texture (1,1,0) is mapped to (255,255,128). Hence the top-right corner of an object is usually light yellow. The brightest part of a color map.</li>
<li>A normal pointing to right of the texture (1,0,0) is mapped to (255,128,128). Hence the right edge of an object is usually light red.</li>
<li>A normal pointing to top of the texture (0,1,0) is mapped to (128,255,128). Hence the top edge of an object is usually light green.</li>
<li>A normal pointing to left of the texture (-1,0,0) is mapped to (0,128,128). Hence the left edge of an object is usually dark cyan.</li>
<li>A normal pointing to bottom of the texture (0,-1,0) is mapped to (128,0,128). Hence the bottom edge of an object is usually dark magenta.</li>
<li>A normal pointing to bottom left corner of the texture (-1,-1,0) is mapped to (0,0,128). Hence the bottom-left corner of an object is usually dark blue. The darkest part of a color map.</li></ul>
<p>Since a normal will be used in the <a href="Dot_product" title="Dot product">dot product</a> calculation for the diffuse lighting computation, we can see that the {0, 0, –1} would be remapped to the {128, 128, 255} values, giving that kind of sky blue color seen in normal maps (blue (z) coordinate is perspective (deepness) coordinate and RG-xy flat coordinates on screen). {0.3, 0.4, –0.866} would be remapped to the ({0.3, 0.4, –0.866}/2+{0.5, 0.5, 0.5})*255={0.15+0.5, 0.2+0.5, -0.433+0.5}*255={0.65, 0.7, 0.067}*255={166, 179, 17} values (<span class="mwe-math-element mwe-math-element-inline"><span class="mwe-math-mathml-inline mwe-math-mathml-a11y" style="display: none;"><math xmlns="http://www.w3.org/1998/Math/MathML" alttext="{\displaystyle 0.3^{2}+0.4^{2}+(-0.866)^{2}=1}">
<semantics>
<mrow class="MJX-TeXAtom-ORD">
<mstyle displaystyle="true" scriptlevel="0">
<msup>
<mn>0.3</mn>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<msup>
<mn>0.4</mn>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msup>
<mo>+</mo>
<mo stretchy="false">(</mo>
<mo>−<!-- − --></mo>
<mn>0.866</mn>
<msup>
<mo stretchy="false">)</mo>
<mrow class="MJX-TeXAtom-ORD">
<mn>2</mn>
</mrow>
</msup>
<mo>=</mo>
<mn>1</mn>
</mstyle>
</mrow>
<annotation encoding="application/x-tex">{\displaystyle 0.3^{2}+0.4^{2}+(-0.866)^{2}=1}</annotation>
</semantics>
</math></span><img src="./3ee1060e39cf67a8db32b280e16f3cf76a4dc060.svg" class="mwe-math-fallback-image-inline mw-invert skin-invert" aria-hidden="true" style="vertical-align: -0.838ex; width:27.962ex; height:3.176ex;" alt="{\displaystyle 0.3^{2}+0.4^{2}+(-0.866)^{2}=1}" loading="lazy"></span>). The sign of the z-coordinate (blue channel) must be flipped to match the normal map's normal vector with that of the eye (the viewpoint or camera) or the light vector. Since negative z values mean that the vertex is in front of the camera (rather than behind the camera) this convention guarantees that the surface shines with maximum strength precisely when the light vector and normal vector are coincident.<sup id="cite_ref-8" class="reference"><a href="#cite_note-8"><span class="cite-bracket">[</span>8<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-heading mw-heading2"><h2 id="Normal_mapping_in_video_games">Normal mapping in video games</h2></div>
<p>Interactive normal map rendering was originally only possible on PixelFlow, a <a href="Parallel_rendering" title="Parallel rendering">parallel rendering</a> machine built at the <a href="University_of_North_Carolina_at_Chapel_Hill" title="University of North Carolina at Chapel Hill">University of North Carolina at Chapel Hill</a>. It was later possible to perform normal mapping on high-end <a href="Silicon_Graphics" title="Silicon Graphics">SGI</a> workstations using multi-pass rendering and <a href="Framebuffer" title="Framebuffer">framebuffer</a> operations<sup id="cite_ref-9" class="reference"><a href="#cite_note-9"><span class="cite-bracket">[</span>9<span class="cite-bracket">]</span></a></sup> or on low end PC hardware with some tricks using paletted textures. However, with the advent of <a href="Shader" title="Shader">shaders</a> in personal computers and game consoles, normal mapping became widespread in the early 2000s, with some of the first games to implement it being <a href="Evolva" title="Evolva">Evolva</a> (2000), <a href="Giants%3A_Citizen_Kabuto" title="Giants: Citizen Kabuto">Giants: Citizen Kabuto</a>, and <a href="Virtua_Fighter_4" title="Virtua Fighter 4">Virtua Fighter 4</a> (2001).<sup id="cite_ref-10" class="reference"><a href="#cite_note-10"><span class="cite-bracket">[</span>10<span class="cite-bracket">]</span></a></sup><sup id="cite_ref-11" class="reference"><a href="#cite_note-11"><span class="cite-bracket">[</span>11<span class="cite-bracket">]</span></a></sup> Normal mapping's popularity for <a href="Real-time_rendering" class="mw-redirect" title="Real-time rendering">real-time rendering</a> is due to its good quality to processing requirements ratio versus other methods of producing similar effects. Much of this efficiency is made possible by <a href="Level_of_detail_(computer_graphics)" title="Level of detail (computer graphics)">distance-indexed detail scaling</a>, a technique which selectively decreases the detail of the normal map of a given texture (cf. <a href="Mipmapping" class="mw-redirect" title="Mipmapping">mipmapping</a>), meaning that more distant surfaces require less complex lighting simulation. Many authoring pipelines use high resolution models <a href="Baking_(computer_graphics)" class="mw-redirect" title="Baking (computer graphics)">baked</a> into low/medium resolution in-game models augmented with normal maps.
</p><p>Basic normal mapping can be implemented in any hardware that supports palettized textures. The first game console to have specialized normal mapping hardware was the Sega <a href="Dreamcast" title="Dreamcast">Dreamcast</a>. However, Microsoft's <a href="Xbox_(console)" title="Xbox (console)">Xbox</a> was the first console to widely use the effect in retail games. Out of the <a href="Sixth_generation_console" class="mw-redirect" title="Sixth generation console">sixth generation consoles</a>, only the <a href="PlayStation_2" title="PlayStation 2">PlayStation 2</a>'s <a href="PlayStation_2#Technical_specifications" title="PlayStation 2">GPU</a> lacks built-in normal mapping support, though it can be simulated using the PlayStation 2 hardware's vector units. Games for the <a href="Xbox_360" title="Xbox 360">Xbox 360</a> and the <a href="PlayStation_3" title="PlayStation 3">PlayStation 3</a> rely heavily on normal mapping and were the first game console generation to make use of <a href="Parallax_mapping" title="Parallax mapping">parallax mapping</a>. The <a href="Nintendo_3DS" title="Nintendo 3DS">Nintendo 3DS</a> has been shown to support normal mapping, as demonstrated by <i><a href="Resident_Evil%3A_Revelations" title="Resident Evil: Revelations">Resident Evil: Revelations</a></i> and <i><a href="Metal_Gear_Solid_3%3A_Snake_Eater" title="Metal Gear Solid 3: Snake Eater">Metal Gear Solid 3: Snake Eater</a></i>.
</p>
<div class="mw-heading mw-heading2"><h2 id="See_also">See also</h2></div>
<ul><li><a href="Reflection_(physics)" title="Reflection (physics)">Reflection (physics)</a></li>
<li><a href="Ambient_occlusion" title="Ambient occlusion">Ambient occlusion</a></li>
<li><a href="Depth_map" title="Depth map">Depth map</a></li>
<li><a href="Baking_(computer_graphics)" class="mw-redirect" title="Baking (computer graphics)">Baking (computer graphics)</a></li>
<li><a href="Tessellation_(computer_graphics)" title="Tessellation (computer graphics)">Tessellation (computer graphics)</a></li>
<li><a href="Bump_mapping" title="Bump mapping">Bump mapping</a></li>
<li><a href="Displacement_mapping" title="Displacement mapping">Displacement mapping</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1239543626">
/* start https://en.wikipedia.org/ */
.mw-parser-output .reflist{margin-bottom:0.5em;list-style-type:decimal}@media screen{.mw-parser-output .reflist{font-size:90%}}.mw-parser-output .reflist .references{font-size:100%;margin-bottom:0;list-style-type:inherit}.mw-parser-output .reflist-columns-2{column-width:30em}.mw-parser-output .reflist-columns-3{column-width:25em}.mw-parser-output .reflist-columns{margin-top:0.3em}.mw-parser-output .reflist-columns ol{margin-top:0}.mw-parser-output .reflist-columns li{page-break-inside:avoid;break-inside:avoid-column}.mw-parser-output .reflist-upper-alpha{list-style-type:upper-alpha}.mw-parser-output .reflist-upper-roman{list-style-type:upper-roman}.mw-parser-output .reflist-lower-alpha{list-style-type:lower-alpha}.mw-parser-output .reflist-lower-greek{list-style-type:lower-greek}.mw-parser-output .reflist-lower-roman{list-style-type:lower-roman}
/* end https://en.wikipedia.org/ */
</style><div class="reflist">
<div class="mw-references-wrap mw-references-columns"><ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><b><a href="#cite_ref-1">^</a></b></span> <span class="reference-text"><style data-mw-deduplicate="TemplateStyles:r1238218222">
/* start https://en.wikipedia.org/ */
.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}.mw-parser-output .citation q{quotes:"\"""\"""'""'"}.mw-parser-output .citation:target{background-color:rgba(0,127,255,0.133)}.mw-parser-output .id-lock-free.id-lock-free a{background:url("./mw/Lock-green.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-limited.id-lock-limited a,.mw-parser-output .id-lock-registration.id-lock-registration a{background:url("./mw/Lock-gray-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-subscription.id-lock-subscription a{background:url("./mw/Lock-red-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .cs1-ws-icon a{background:url("./mw/Wikisource-logo.svg")right 0.1em center/12px no-repeat}body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-free a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-limited a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-registration a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-subscription a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .cs1-ws-icon a{background-size:contain;padding:0 1em 0 0}.mw-parser-output .cs1-code{color:inherit;background:inherit;border:none;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;color:var(--color-error,#d33)}.mw-parser-output .cs1-visible-error{color:var(--color-error,#d33)}.mw-parser-output .cs1-maint{display:none;color:#085;margin-left:0.3em}.mw-parser-output .cs1-kern-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}@media screen{.mw-parser-output .cs1-format{font-size:95%}html.skin-theme-clientpref-night .mw-parser-output .cs1-maint{color:#18911f}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .cs1-maint{color:#18911f}}
/* end https://en.wikipedia.org/ */
</style><cite class="citation web cs1"><a rel="nofollow" class="external text" href="https://learnopengl.com/Advanced-Lighting/Normal-Mapping">"LearnOpenGL - Normal Mapping"</a>. <i>learnopengl.com</i><span class="reference-accessdate">. Retrieved <span class="nowrap">2024-05-21</span></span>.</cite></span>
</li>
<li id="cite_note-2"><span class="mw-cite-backlink"><b><a href="#cite_ref-2">^</a></b></span> <span class="reference-text">Blinn. <i><a rel="nofollow" class="external text" href="https://www.microsoft.com/en-us/research/wp-content/uploads/1978/01/p286-blinn.pdf">Simulation of Wrinkled Surfaces</a></i>, Siggraph 1978</span>
</li>
<li id="cite_note-3"><span class="mw-cite-backlink"><b><a href="#cite_ref-3">^</a></b></span> <span class="reference-text">Krishnamurthy and Levoy, <i><a rel="nofollow" class="external text" href="http://www.graphics.stanford.edu/papers/surfacefitting/">Fitting Smooth Surfaces to Dense Polygon Meshes</a></i>, SIGGRAPH 1996</span>
</li>
<li id="cite_note-4"><span class="mw-cite-backlink"><b><a href="#cite_ref-4">^</a></b></span> <span class="reference-text">Cohen et al., <a rel="nofollow" class="external text" href="http://www.cs.unc.edu/~geom/APS/APS.pdf">Appearance-Preserving Simplification</a>, SIGGRAPH 1998 <b>(PDF)</b></span>
</li>
<li id="cite_note-5"><span class="mw-cite-backlink"><b><a href="#cite_ref-5">^</a></b></span> <span class="reference-text">Cignoni et al., <a rel="nofollow" class="external text" href="http://vcg.isti.cnr.it/publications/papers/rocchini.pdf">A general method for preserving attribute values on simplified meshes</a>, IEEE Visualization 1998 <b>(PDF)</b></span>
</li>
<li id="cite_note-6"><span class="mw-cite-backlink"><b><a href="#cite_ref-6">^</a></b></span> <span class="reference-text"><cite id="CITEREFAkenine-MöllerHainesHoffmanPesce2018" class="citation book cs1">Akenine-Möller, Tomas; Haines, Eric; Hoffman, Naty; Pesce, Angelo; Iwanicki, Michał; Hillaire, Sébastien (2018). <a rel="nofollow" class="external text" href="https://www.realtimerendering.com/"><i>Real-Time Rendering 4th Edition</i></a> (4 ed.). Boca Raton, FL, USA: A K Peters/CRC Press. p. 57. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a> <bdi>978-1-13862-700-0</bdi><span class="reference-accessdate">. Retrieved <span class="nowrap">2 August</span> 2024</span>.</cite></span>
</li>
<li id="cite_note-7"><span class="mw-cite-backlink"><b><a href="#cite_ref-7">^</a></b></span> <span class="reference-text">Mikkelsen, <a rel="nofollow" class="external text" href="http://image.diku.dk/projects/media/morten.mikkelsen.08.pdf">Simulation of Wrinkled Surfaces Revisited</a>, 2008 <b>(PDF)</b></span>
</li>
<li id="cite_note-8"><span class="mw-cite-backlink"><b><a href="#cite_ref-8">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="https://learnopengl.com/Advanced-Lighting/Normal-Mapping">"LearnOpenGL - Normal Mapping"</a>. <i>learnopengl.com</i><span class="reference-accessdate">. Retrieved <span class="nowrap">2021-10-19</span></span>.</cite></span>
</li>
<li id="cite_note-9"><span class="mw-cite-backlink"><b><a href="#cite_ref-9">^</a></b></span> <span class="reference-text">Heidrich and Seidel, <a rel="nofollow" class="external text" href="http://www.cs.ubc.ca/~heidrich/Papers/Siggraph.99.pdf">Realistic, Hardware-accelerated Shading and Lighting</a> <a rel="nofollow" class="external text" href="https://web.archive.org/web/20050129211042/http://www.cs.ubc.ca/~heidrich/Papers/Siggraph.99.pdf">Archived</a> 2005-01-29 at the <a href="Wayback_Machine" title="Wayback Machine">Wayback Machine</a>, <a href="SIGGRAPH" title="SIGGRAPH">SIGGRAPH</a> 1999 <b>(<a href="PDF" title="PDF">PDF</a>)</b></span>
</li>
<li id="cite_note-10"><span class="mw-cite-backlink"><b><a href="#cite_ref-10">^</a></b></span> <span class="reference-text"><cite class="citation web cs1"><a rel="nofollow" class="external text" href="https://segaretro.org/Virtua_Fighter_4">"Virtua Fighter 4"</a>. <i>Sega Retro</i>. 2023-11-30<span class="reference-accessdate">. Retrieved <span class="nowrap">2024-03-03</span></span>.</cite></span>
</li>
<li id="cite_note-11"><span class="mw-cite-backlink"><b><a href="#cite_ref-11">^</a></b></span> <span class="reference-text"><cite class="citation web cs1 cs1-prop-foreign-lang-source"><a rel="nofollow" class="external text" href="https://as.com/meristation/2006/08/01/reportajes/1154449800_036749.html">"Tecnologías gráficas en los juegos"</a>. <i>Meristation</i> (in Spanish). 2012-04-18<span class="reference-accessdate">. Retrieved <span class="nowrap">2024-03-03</span></span>.</cite></span>
</li>
</ol></div></div>
<div class="mw-heading mw-heading2"><h2 id="External_links">External links</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1290876196">
/* start https://en.wikipedia.org/ */
.mw-parser-output .side-box{margin:4px 0;box-sizing:border-box;border:1px solid #aaa;font-size:88%;line-height:1.25em;background-color:var(--background-color-interactive-subtle,#f8f9fa);display:flow-root}.mw-parser-output .infobox .side-box{font-size:100%}.mw-parser-output .side-box-abovebelow,.mw-parser-output .side-box-text{padding:0.25em 0.9em}.mw-parser-output .side-box-image{padding:2px 0 2px 0.9em;text-align:center}.mw-parser-output .side-box-imageright{padding:2px 0.9em 2px 0;text-align:center}@media(min-width:500px){.mw-parser-output .side-box-flex{display:flex;align-items:center}.mw-parser-output .side-box-text{flex:1;min-width:0}}@media(min-width:720px){.mw-parser-output .side-box{width:238px}.mw-parser-output .side-box-right{clear:right;float:right;margin-left:1em}.mw-parser-output .side-box-left{margin-right:1em}}
/* end https://en.wikipedia.org/ */
</style><style data-mw-deduplicate="TemplateStyles:r1237033735">
/* start https://en.wikipedia.org/ */
@media print{body.ns-0 .mw-parser-output .sistersitebox{display:none!important}}@media screen{html.skin-theme-clientpref-night .mw-parser-output .sistersitebox img[src*="Wiktionary-logo-en-v2.svg"]{background-color:white}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .sistersitebox img[src*="Wiktionary-logo-en-v2.svg"]{background-color:white}}
/* end https://en.wikipedia.org/ */
</style><div class="side-box side-box-right sistersitebox"><style data-mw-deduplicate="TemplateStyles:r1126788409">
/* start https://en.wikipedia.org/ */
.mw-parser-output .plainlist ol,.mw-parser-output .plainlist ul{line-height:inherit;list-style:none;margin:0;padding:0}.mw-parser-output .plainlist ol li,.mw-parser-output .plainlist ul li{margin-bottom:0}
/* end https://en.wikipedia.org/ */
</style>
<div class="side-box-flex">
<div class="side-box-image"><span class="noviewer" typeof="mw:File"></span></div>
<div class="side-box-text plainlist">Wikimedia Commons has media related to <span style="font-weight: bold; font-style: italic;"><a href="https://commons.wikimedia.org/wiki/Category:Normal_mapping" class="extiw external" title="commons:Category:Normal mapping">Normal mapping</a></span>.</div></div>
</div>
<ul><li><a rel="nofollow" class="external text" href="https://web.archive.org/web/20160820195558/http://www.falloutsoftware.com/tutorials/gl/normal-map.html">Normal Map Tutorial</a> Per-pixel logic behind Dot3 Normal Mapping</li>
<li><a rel="nofollow" class="external text" href="https://cpetry.github.io/NormalMap-Online">NormalMap-Online</a> Free Generator inside Browser</li>
<li><a rel="nofollow" class="external text" href="https://web.archive.org/web/20150503205556/http://sunandblackcat.com/tipFullView.php?l=eng&topicid=7">Normal Mapping on sunandblackcat.com</a></li>
<li><a rel="nofollow" class="external text" href="https://web.archive.org/web/20160827174956/https://www.blender.org/manual/render/blender_render/textures/influence/material/bump_and_normal.html">Blender Normal Mapping</a></li>
<li><a rel="nofollow" class="external text" href="https://web.archive.org/web/20050308073824/http://vcg.isti.cnr.it/activities/geometryegraphics/bumpmapping.html">Normal Mapping with paletted textures</a> using old OpenGL extensions.</li>
<li><a rel="nofollow" class="external text" href="http://zarria.net/nrmphoto/nrmphoto.html">Normal Map Photography</a> Creating normal maps manually by layering digital photographs</li>
<li><a rel="nofollow" class="external text" href="http://www.3dkingdoms.com/tutorial.htm">Normal Mapping Explained</a></li>
<li><a rel="nofollow" class="external text" href="https://sourceforge.net/projects/simplenormalmapper/">Simple Normal Mapper</a> Open Source normal map generator</li></ul>
<div class="navbox-styles"><style data-mw-deduplicate="TemplateStyles:r1129693374">
/* start https://en.wikipedia.org/ */
.mw-parser-output .hlist dl,.mw-parser-output .hlist ol,.mw-parser-output .hlist ul{margin:0;padding:0}.mw-parser-output .hlist dd,.mw-parser-output .hlist dt,.mw-parser-output .hlist li{margin:0;display:inline}.mw-parser-output .hlist.inline,.mw-parser-output .hlist.inline dl,.mw-parser-output .hlist.inline ol,.mw-parser-output .hlist.inline ul,.mw-parser-output .hlist dl dl,.mw-parser-output .hlist dl ol,.mw-parser-output .hlist dl ul,.mw-parser-output .hlist ol dl,.mw-parser-output .hlist ol ol,.mw-parser-output .hlist ol ul,.mw-parser-output .hlist ul dl,.mw-parser-output .hlist ul ol,.mw-parser-output .hlist ul ul{display:inline}.mw-parser-output .hlist .mw-empty-li{display:none}.mw-parser-output .hlist dt::after{content:": "}.mw-parser-output .hlist dd::after,.mw-parser-output .hlist li::after{content:" · ";font-weight:bold}.mw-parser-output .hlist dd:last-child::after,.mw-parser-output .hlist dt:last-child::after,.mw-parser-output .hlist li:last-child::after{content:none}.mw-parser-output .hlist dd dd:first-child::before,.mw-parser-output .hlist dd dt:first-child::before,.mw-parser-output .hlist dd li:first-child::before,.mw-parser-output .hlist dt dd:first-child::before,.mw-parser-output .hlist dt dt:first-child::before,.mw-parser-output .hlist dt li:first-child::before,.mw-parser-output .hlist li dd:first-child::before,.mw-parser-output .hlist li dt:first-child::before,.mw-parser-output .hlist li li:first-child::before{content:" (";font-weight:normal}.mw-parser-output .hlist dd dd:last-child::after,.mw-parser-output .hlist dd dt:last-child::after,.mw-parser-output .hlist dd li:last-child::after,.mw-parser-output .hlist dt dd:last-child::after,.mw-parser-output .hlist dt dt:last-child::after,.mw-parser-output .hlist dt li:last-child::after,.mw-parser-output .hlist li dd:last-child::after,.mw-parser-output .hlist li dt:last-child::after,.mw-parser-output .hlist li li:last-child::after{content:")";font-weight:normal}.mw-parser-output .hlist ol{counter-reset:listitem}.mw-parser-output .hlist ol>li{counter-increment:listitem}.mw-parser-output .hlist ol>li::before{content:" "counter(listitem)"\a0 "}.mw-parser-output .hlist dd ol>li:first-child::before,.mw-parser-output .hlist dt ol>li:first-child::before,.mw-parser-output .hlist li ol>li:first-child::before{content:" ("counter(listitem)"\a0 "}
/* end https://en.wikipedia.org/ */
</style><style data-mw-deduplicate="TemplateStyles:r1236075235">
/* start https://en.wikipedia.org/ */
.mw-parser-output .navbox{box-sizing:border-box;border:1px solid #a2a9b1;width:100%;clear:both;font-size:88%;text-align:center;padding:1px;margin:1em auto 0}.mw-parser-output .navbox .navbox{margin-top:0}.mw-parser-output .navbox+.navbox,.mw-parser-output .navbox+.navbox-styles+.navbox{margin-top:-1px}.mw-parser-output .navbox-inner,.mw-parser-output .navbox-subgroup{width:100%}.mw-parser-output .navbox-group,.mw-parser-output .navbox-title,.mw-parser-output .navbox-abovebelow{padding:0.25em 1em;line-height:1.5em;text-align:center}.mw-parser-output .navbox-group{white-space:nowrap;text-align:right}.mw-parser-output .navbox,.mw-parser-output .navbox-subgroup{background-color:#fdfdfd}.mw-parser-output .navbox-list{line-height:1.5em;border-color:#fdfdfd}.mw-parser-output .navbox-list-with-group{text-align:left;border-left-width:2px;border-left-style:solid}.mw-parser-output tr+tr>.navbox-abovebelow,.mw-parser-output tr+tr>.navbox-group,.mw-parser-output tr+tr>.navbox-image,.mw-parser-output tr+tr>.navbox-list{border-top:2px solid #fdfdfd}.mw-parser-output .navbox-title{background-color:#ccf}.mw-parser-output .navbox-abovebelow,.mw-parser-output .navbox-group,.mw-parser-output .navbox-subgroup .navbox-title{background-color:#ddf}.mw-parser-output .navbox-subgroup .navbox-group,.mw-parser-output .navbox-subgroup .navbox-abovebelow{background-color:#e6e6ff}.mw-parser-output .navbox-even{background-color:#f7f7f7}.mw-parser-output .navbox-odd{background-color:transparent}.mw-parser-output .navbox .hlist td dl,.mw-parser-output .navbox .hlist td ol,.mw-parser-output .navbox .hlist td ul,.mw-parser-output .navbox td.hlist dl,.mw-parser-output .navbox td.hlist ol,.mw-parser-output .navbox td.hlist ul{padding:0.125em 0}.mw-parser-output .navbox .navbar{display:block;font-size:100%}.mw-parser-output .navbox-title .navbar{float:left;text-align:left;margin-right:0.5em}body.skin--responsive .mw-parser-output .navbox-image img{max-width:none!important}@media print{body.ns-0 .mw-parser-output .navbox{display:none!important}}
/* end https://en.wikipedia.org/ */
</style></div><div role="navigation" class="navbox" aria-labelledby="Texture_mapping_techniques62" style="padding:3px"><table class="nowraplinks mw-collapsible autocollapse navbox-inner" style="border-spacing:0;background:transparent;color:inherit"><tbody><tr><th scope="col" class="navbox-title" colspan="2"><style data-mw-deduplicate="TemplateStyles:r1239400231">
/* start https://en.wikipedia.org/ */
.mw-parser-output .navbar{display:inline;font-size:88%;font-weight:normal}.mw-parser-output .navbar-collapse{float:left;text-align:left}.mw-parser-output .navbar-boxtext{word-spacing:0}.mw-parser-output .navbar ul{display:inline-block;white-space:nowrap;line-height:inherit}.mw-parser-output .navbar-brackets::before{margin-right:-0.125em;content:"[ "}.mw-parser-output .navbar-brackets::after{margin-left:-0.125em;content:" ]"}.mw-parser-output .navbar li{word-spacing:-0.125em}.mw-parser-output .navbar a>span,.mw-parser-output .navbar a>abbr{text-decoration:inherit}.mw-parser-output .navbar-mini abbr{font-variant:small-caps;border-bottom:none;text-decoration:none;cursor:inherit}.mw-parser-output .navbar-ct-full{font-size:114%;margin:0 7em}.mw-parser-output .navbar-ct-mini{font-size:114%;margin:0 4em}html.skin-theme-clientpref-night .mw-parser-output .navbar li a abbr{color:var(--color-base)!important}@media(prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .navbar li a abbr{color:var(--color-base)!important}}@media print{.mw-parser-output .navbar{display:none!important}}
/* end https://en.wikipedia.org/ */
</style><div id="Texture_mapping_techniques62" style="font-size:114%;margin:0 4em"><a href="Texture_mapping" title="Texture mapping">Texture mapping techniques</a></div></th></tr><tr><th scope="row" class="navbox-group" style="width:1%">Local</th><td class="navbox-list-with-group navbox-list navbox-odd hlist" style="width:100%;padding:0"><div style="padding:0 0.25em">
<ul><li><a href="Displacement_mapping" title="Displacement mapping">Displacement mapping</a></li>
<li><a href="Parallax_mapping" title="Parallax mapping">Parallax mapping</a></li>
<li><a href="UV_mapping" title="UV mapping">UV mapping</a></li>
<li><a href="UVW_mapping" title="UVW mapping">UVW mapping</a></li>
<li><a href="Relief_mapping_(computer_graphics)" title="Relief mapping (computer graphics)"> Relief mapping</a></li>
<li><a href="Alpha_mapping" title="Alpha mapping">Alpha mapping</a></li>
<li><a href="Bump_mapping" title="Bump mapping">Bump mapping</a></li>
<li><a href="Ambient_occlusion" title="Ambient occlusion"> Occlusion mapping</a></li>
<li><a href="Specularity#Specular_maps" title="Specularity"> Specular mapping</a></li></ul>
</div></td></tr><tr><th scope="row" class="navbox-group" style="width:1%">Environment</th><td class="navbox-list-with-group navbox-list navbox-even hlist" style="width:100%;padding:0"><div style="padding:0 0.25em">
<ul><li><a href="Cube_mapping" title="Cube mapping">Cube mapping</a></li>
<li><a href="Sphere_mapping" title="Sphere mapping">Sphere mapping</a></li>
<li><a href="Environment_mapping" class="mw-redirect" title="Environment mapping">Environment mapping</a></li></ul>
</div></td></tr></tbody></table></div></div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2025-07-28" href="https://en.wikipedia.org/wiki/?title=Normal_mapping&oldid=1302955283">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
</body></html>